Adding some more judges, here and there.
[and.git] / lib / Mi manual de algoritmos / version_maraton_nacional_2008 / manual.tex
blobb26aac03eb52d882a4bdbd2587b5e5595f5f9347
1 \documentclass[10pt,letterpaper]{article}
3 %---------------------------------------------------------------
4 \usepackage[utf8]{inputenc}
5 \usepackage[spanish]{babel}
6 \usepackage{listings}
7 \usepackage[usenames,dvipsnames]{color}
8 \usepackage{amsmath}
9 \usepackage{verbatim}
10 \usepackage{hyperref}
11 %\usepackage{color}
12 %---------------------------------------------------------------
14 \setlength{\topmargin}{-1.0in}
15 \setlength{\textheight}{9.5in}
16 \setlength{\evensidemargin}{0.0in}
17 \setlength{\oddsidemargin}{0.0in}
18 \setlength{\textwidth}{6.5in}
20 \begin{document}
22 %---------------------------------------------------------------
23 \title{Resumen de algoritmos para torneos de programación}
24 \author{Andrés Mejía}
25 \date{\today}
26 \maketitle
27 %---------------------------------------------------------------
29 %---------------------------------------------------------------
30 \tableofcontents
31 %\lstlistoflistings
32 \lstloadlanguages{C++}
33 %---------------------------------------------------------------
34 %---------------------------------------------------------------
35 \section{Teoría de números}
36 %---------------------------------------------------------------
37 \subsection{Big mod}
38 \input{./src/number_theory/bigmod}%.tex
40 \subsection{Criba de Eratóstenes}
41 \small
42 \textbf{Field-testing:}
43 \begin{itemize}
44 \item \emph{SPOJ} - 2912 - Super Primes
45 \item \emph{Live Archive} - 3639 - Prime Path
46 \end{itemize}
48 \normalsize
49 Marca los números primos en un arreglo. Algunos tiempos de ejecución:
50 \begin{center}
51 \begin{tabular}{c c}
52 \hline\hline
53 SIZE & Tiempo (s) \\ [0.5ex]
54 \hline
55 100000 & 0.003 \\
56 1000000 & 0.060 \\
57 10000000 & 0.620 \\
58 100000000 & 7.650 \\ [1ex]
59 \hline
60 \end{tabular}
61 \end{center}
63 \input{./src/number_theory/criba}%.tex
65 \subsection{Divisores de un número}
66 Este algoritmo imprime todos los divisores de un número (en desorden) en O($\sqrt{n}$).
67 Hasta 4294967295 (máximo \textit{unsigned long}) responde instantaneamente. Se puede
68 forzar un poco más usando \textit{unsigned long long} pero más allá de $10^{12}$ empieza a
69 responder muy lento.
71 \bigskip
73 \input{./src/number_theory/divisores}%.tex
75 \section{Combinatoria}
76 \subsection{Cuadro resumen}
77 Fórmulas para combinaciones y permutaciones:
78 \begin{center}
79 \renewcommand{\arraystretch}{2} %Multiplica la altura de cada fila de la tabla por 2
80 %Si quiero aumentar el tamaño de una fila en particular insertar \rule{0cm}{1cm} en esa fila.
81 \begin{tabular}{| c | c | c |}
82 \hline
83 \textit{Tipo} & \textit{¿Se permite la repetición?} & \textit{Fórmula} \\ [1.5ex]
84 \hline\hline
86 $r$-permutaciones & No & $ \displaystyle\frac{n!}{(n-r)!} $ \\ [1.5ex]
87 \hline
88 $r$-combinaciones & No & $ \displaystyle\frac{n!}{r!(n-r)!} $ \\ [1.5ex]
89 \hline
90 $r$-permutaciones & Sí & $ \displaystyle n^{r} $ \\
91 \hline
92 $r$-combinaciones & Sí & $ \displaystyle\frac{(n+r-1)!}{r!(n-1)!} $ \\ [1.5ex]
93 \hline
94 \end{tabular}
95 \renewcommand{\arraystretch}{1}
96 \end{center}
97 Tomado de \textit{Matemática discreta y sus aplicaciones}, Kenneth Rosen, 5${}^{\hbox{ta}}$ edición, McGraw-Hill, página 315.
99 \subsection{Combinaciones, coeficientes binomiales, triángulo de Pascal}
100 \emph{Complejidad:} $ O(n^2) $ \\
101 $$ {n \choose k} = \left\{
102 \begin{array}{c l}
103 1 & k = 0\\
104 1 & n = k\\
105 \displaystyle {n - 1 \choose k - 1} + {n - 1 \choose k} & \mbox{en otro caso}\\
106 \end{array}
107 \right.
110 \input{./src/combinatoria/pascal_triangle}%.tex
112 \bigskip
113 \textbf{Nota:} $ \displaystyle {n \choose k } $ está indefinido en el código anterior si $ n > k$. ¡La tabla puede estar llena con cualquier basura del compilador!
115 \subsection{Permutaciones con elementos indistinguibles}
116 El número de permutaciones \underline{diferentes} de $n$ objetos, donde hay $n_{1}$ objetos indistinguibles de tipo 1,
117 $n_{2}$ objetos indistinguibles de tipo 2, ..., y $n_{k}$ objetos indistinguibles de tipo $k$, es
119 \frac{n!}{n_{1}!n_{2}! \cdots n_{k}!}
121 \textbf{Ejemplo:} Con las letras de la palabra \texttt{PROGRAMAR} se pueden formar $ \displaystyle \frac{9!}{2! \cdot 3!} =
122 30240 $ permutaciones \underline{diferentes}.
123 \subsection{Desordenes, desarreglos o permutaciones completas}
125 Un desarreglo es una permutación donde ningún elemento $i$ está en la
126 posición $i$-ésima. Por ejemplo, \textit{4213} es un desarreglo de 4 elementos pero
127 \textit{3241} no lo es porque el 2 aparece en la posición 2.
129 Sea $D_{n}$ el número de desarreglos de $n$ elementos, entonces:
130 $$ {D_{n}} = \left\{
131 \begin{array}{c l}
132 1 & n = 0\\
133 0 & n = 1\\
134 (n-1)(D_{n-1} + D_{n-2}) & n \geq 2\\
135 \end{array}
136 \right.
138 Usando el principio de inclusión-exclusión, también se puede encontrar la fórmula
140 D_{n} = n!\left [ 1 - \frac{1}{1!} + \frac{1}{2!} - \frac{1}{3!} + \cdots + (-1)^{n}\frac{1}{n!} \right ]
141 = n! \sum_{i=0}^{n} \frac{(-1)^{i}}{i!}
144 \section{Grafos}
145 \subsection{Algoritmo de Dijkstra}
146 El peso de todas las aristas debe ser no negativo.
148 \input{./src/grafos/dijkstra}%.tex
150 \subsection{Minimum spanning tree: Algoritmo de Prim}
152 \input{./src/grafos/prim}%.tex
154 \subsection{Minimum spanning tree: Algoritmo de Kruskal + Union-Find}
155 \input{./src/grafos/kruskal}%.tex
157 \subsection{Algoritmo de Floyd-Warshall}
158 \emph{Complejidad:} $ O(n^3) $ \\
159 Se asume que no hay ciclos de costo negativo.
160 \input{./src/grafos/floyd}%.tex
162 \subsection{Algoritmo de Bellman-Ford}
163 Si no hay ciclos de coste negativo, encuentra la distancia más corta entre un nodo
164 y todos los demás. Si sí hay, permite saberlo. \\
165 El coste de las aristas \underline{} puede ser negativo.
166 \input{./src/grafos/bellman}%.tex
168 \subsection{Puntos de articulación}
169 \input{./src/grafos/puntos_articulacion}%.tex
171 \subsection{Máximo flujo: Método de Ford-Fulkerson, algoritmo de Edmonds-Karp}
172 \medskip
173 El algoritmo de Edmonds-Karp es una modificación al método de Ford-Fulkerson. Este último
174 utiliza DFS para hallar un camino de aumentación, pero la sugerencia de Edmonds-Karp
175 es utilizar BFS que lo hace más eficiente en algunos grafos.
176 \input{./src/grafos/ford_fulkerson}%.tex
178 \section{Programación dinámica}
179 \subsection{Longest common subsequence}
180 \input{./src/dp/lcs}%.tex
182 \subsection{Partición de troncos}
183 Este problema es similar al problema de \textit{Matrix Chain Multiplication}. Se tiene
184 un tronco de longitud $n$, y $m$ puntos de corte en el tronco. Se puede hacer un corte a la vez,
185 cuyo costo es igual a la longitud del tronco. ¿Cuál es el mínimo costo para partir todo el tronco
186 en pedacitos individuales?
188 \medskip
189 \textbf{Ejemplo:} Se tiene un tronco de longitud 10. Los puntos de corte son 2, 4, y 7. El mínimo
190 costo para partirlo es 20, y se obtiene así:
191 \begin{itemize}
192 \item Partir el tronco (0, 10) por 4. Vale 10 y quedan los troncos (0, 4) y (4, 10).
193 \item Partir el tronco (0, 4) por 2. Vale 4 y quedan los troncos (0, 2), (2, 4) y (4, 10).
194 \item No hay que partir el tronco (0, 2).
195 \item No hay que partir el tronco (2, 4).
196 \item Partir el tronco (4, 10) por 7. Vale 6 y quedan los troncos (4, 7) y (7, 10).
197 \item No hay que partir el tronco (4, 7).
198 \item No hay que partir el tronco (7, 10).
199 \item El costo total es $10+4+6 = 20$.
200 \end{itemize}
202 \medskip
203 El algoritmo es $O(n^3)$, pero optimizable a $O(n^2)$ con una tabla adicional:
204 \input{./src/dp/particion_troncos}%.tex
206 \section{Geometría}
207 \subsection{Área de un polígono}
208 Si P es un polígono simple (no se intersecta a sí mismo) su área está dada por: \\
210 $ A(P) = \frac{1}{2} \displaystyle\sum_{i=0}^{n-1} (x_{i} \cdot y_{i+1} - x_{i+1} \cdot y_{i}) $ \\
211 \bigskip
212 \input{./src/geometria/polygon_area}%.tex
214 \subsection{Centro de masa de un polígono}
215 Si P es un polígono simple (no se intersecta a sí mismo) su centro de masa está dado por: \\
217 $ \displaystyle\bar{C}_{x} = \frac{ \displaystyle\iint_{R} x \, dA }{M} = \frac{1}{6M}\sum_{i=1}^{n} (y_{i+1} - y_{i}) (x_{i+1}^2 + x_{i+1} \cdot x_{i} + x_{i}^2) $
219 \medskip
221 $\displaystyle\bar{C}_{y} = \frac{ \displaystyle\iint_{R} y \, dA }{M} = \frac{1}{6M} \sum_{i=1}^{n} (x_{i} - x_{i+1}) (y_{i+1}^2 + y_{i+1} \cdot y_{i} + y_{i}^2)$
223 \medskip
225 Donde $ M $ es el área del polígono. \\
227 Otra posible fórmula equivalente:
229 $ \displaystyle\bar{C}_{x} = \frac{1}{6A} \sum_{i=0}^{n-1} (x_{i} + x_{i+1}) (x_{i} \cdot y_{i+1} - x_{i+1} \cdot y_{i}) $
231 \medskip
233 $ \displaystyle\bar{C}_{y} = \frac{1}{6A} \sum_{i=0}^{n-1} (y_{i} + y_{i+1}) (x_{i} \cdot y_{i+1} - x_{i+1} \cdot y_{i}) $
236 \subsection{Convex hull: Graham Scan}
237 \emph{Complejidad:} $ O(n \log_{2}{n}) $
238 \input{./src/geometria/grahamscan}%.tex
240 \subsection{Convex hull: Andrew's monotone chain}
241 \emph{Complejidad:} $ O(n \log_{2}{n}) $
242 \input{./src/geometria/monotonechain}%.tex
244 \subsection{Mínima distancia entre un punto y un segmento}
245 \input{./src/geometria/distance_point_to_segment}%.tex
247 \subsection{Mínima distancia entre un punto y una recta}
248 \input{./src/geometria/distance_point_to_line}%.tex
250 \subsection{Determinar si un polígono es convexo}
251 \input{./src/geometria/is_convex_polygon}%.tex
253 \subsection{Determinar si un punto está dentro de un polígono convexo}
254 \input{./src/geometria/is_inside_convex_polygon}%.tex
256 \subsection{Determinar si un punto está dentro de un polígono cualquiera}
257 \large{\textbf{ADVERTENCIA:}} Código no probado.
258 \input{./src/geometria/is_inside_concave_polygon}%.tex
260 %---------------------------------------------------------------
261 \section{Misceláneo}
262 \subsection{El \textit{parser} más rápido del mundo}
263 \begin{itemize}
264 \item Cada no-terminal: un método
265 \item Cada lado derecho: invocar los métodos de los no-terminales o
266 \item Cada terminal: invocar proceso \textit{match}
267 \item Alternativas en una producción: se hace un \textit{if}
268 \end{itemize}
269 \medskip
270 No funciona con gramáticas recursivas por izquierda ó en las que en algún momento haya
271 varias posibles escogencias que empiezan por el mismo caracter (En ambos casos la gramática se puede factorizar).
273 \medskip
274 \textbf{Ejemplo:} Para la gramática:
276 A \longrightarrow (A)A
277 $$ $$
278 A \longrightarrow \epsilon
281 \input{./src/misc/parser_recursivo_desc}%.tex
284 \section{Java}
285 \subsection{Entrada desde entrada estándar}
286 Este primer método es muy fácil pero es mucho más ineficiente porque utiliza Scanner en vez de BufferedReader: \\
287 \input{./src/java/io_estandar_easy}%.tex
289 \bigskip
291 Este segundo es más rápido: \\
292 \input{./src/java/io_estandar}%.tex
293 \subsection{Entrada desde archivo}
294 \input{./src/java/io_file}%.tex
296 \subsection{Mapas y sets}
297 Programa de ejemplo:
298 \input{./src/java/maps_sets}%.tex
299 \bigskip
300 La salida de este programa es: \\
302 \ttfamily
303 \fbox{\parbox{2.0in}{
304 Maps\\
305 m.size() = 1\\
306 465\\
307 null\\
309 Sets\\
310 54 presente.\\
311 s.size() = 3\\
312 54\\
313 3576\\
314 1000000007\\
315 s.size() = 0\\
318 \\ \normalfont\normalsize
319 \bigskip
320 Si quiere usarse una clase propia como llave del mapa o como elemento del set, la clase debe implementar
321 algunos métodos especiales: Si va a usarse un TreeMap ó TreeSet hay que implementar los métodos \texttt{compareTo} y
322 \texttt{equals} de la interfaz \texttt{Comparable} como en la sección \ref{colas_de_prioridad_java}. Si va a usarse
323 un HashMap ó HashSet hay más complicaciones.\\
324 \smallskip
325 \textbf{Sugerencia:} Inventar una manera de codificar y decodificar la clase en una String o un Integer y meter esa representación en el mapa o set: esas clases ya tienen los métodos implementados.
327 \subsection{Colas de prioridad}
328 \label{colas_de_prioridad_java}
329 Hay que implementar unos métodos. Veamos un ejemplo: \\
330 \input{./src/java/priority_queue}%.tex
331 \bigskip
332 La salida de este programa es: \\
334 \ttfamily
335 \fbox{\parbox{2.0in}{
336 peso = 0, destino = 12\\
337 peso = 0, destino = 8\\
338 peso = 0, destino = 13\\
339 peso = 3, destino = 7\\
340 peso = 1876, destino = 4\\
343 \\ \normalfont\normalsize
344 \medskip
345 Vemos que la función de comparación que definimos no tiene en cuenta \texttt{destino},
346 por eso no desempata cuando dos \texttt{Items} tienen el mismo \texttt{peso} si no que escoge
347 cualquiera de manera arbitraria.
349 \section{C++}
350 \subsection{Entrada desde archivo}
351 \input{./src/c++/io_file}%.tex
353 \subsection{Strings con caractéres especiales}
354 \input{./src/c++/unicode}%.tex
356 \emph{Nota}: Como alternativa a la función getline, se pueden utilizar las funciones fgetws y fputws, y más adelante swscanf y wprintf:
357 \input{./src/c++/fgetws}%.tex
359 \end{document}